package com.nondo.rdp.auth.security.auth;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.nondo.rdp.auth.common.exception.enums.SecurityExceptionEnums;
import com.nondo.rdp.auth.security.exceptions.AuthMethodNotSupportedException;
import com.nondo.rdp.auth.security.exceptions.JwtExpiredTokenException;
import com.nondo.rdp.core.model.View;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

/**
 * AwareAuthenticationFailureHandler
 *
 * @author linfeng
 * @since 2017/7/30
 */
@Component
public class AwareAuthenticationFailureHandler implements AuthenticationFailureHandler {
    private final ObjectMapper mapper;

    @Autowired
    public AwareAuthenticationFailureHandler(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                        AuthenticationException e) throws IOException, ServletException {

        response.setStatus(HttpStatus.OK.value());
        response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);

        if (e instanceof BadCredentialsException) {
            mapper.writeValue(response.getWriter(), View.of(SecurityExceptionEnums.AUTHENTICATION.code, e.getMessage()));
        } else if (e instanceof JwtExpiredTokenException) {
            mapper.writeValue(response.getWriter(), View.of(SecurityExceptionEnums.JWT_TOKEN_EXPIRED));
        } else if (e instanceof AuthMethodNotSupportedException) {
            mapper.writeValue(response.getWriter(), View.of(SecurityExceptionEnums.AUTHENTICATION.code, e.getMessage()));
        }else if (e instanceof InsufficientAuthenticationException) { 
        	mapper.writeValue(response.getWriter(), View.of(SecurityExceptionEnums.AUTHENTICATION.code, e.getMessage()));
        }else {
            mapper.writeValue(response.getWriter(), View.of(SecurityExceptionEnums.UNAUTHORIZED));
        }

    }
}
